package com.xmall.product.controller;

import cn.hutool.core.util.IdUtil;
import com.xmall.aspect.OperateRecord;
import com.xmall.aspect.RepeatSubmit;
import com.xmall.define.base.Result;
import com.xmall.define.dict.OperateTypeEnum;
import com.xmall.product.define.dto.group.AttrOptionDto;
import com.xmall.product.define.dto.group.GroupDto;
import com.xmall.product.define.dto.saleAttr.SpuSaleAttrDto;
import com.xmall.product.define.request.group.BuildAttrOptionRequest;
import com.xmall.product.define.request.group.BuildAttrRequest;
import com.xmall.product.define.request.group.GroupQueryParams;
import com.xmall.product.define.request.group.GroupUpdateRequest;
import com.xmall.product.service.ICategoryService;
import com.xmall.product.service.IGroupService;
import com.xmall.validate.group.AddGroup;
import com.xmall.validate.group.UpdateGroup;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * 属性分组
 */
@RestController
@RequestMapping("/service/product/group")
public class GroupController {

    @Resource
    private IGroupService groupService;

    @Resource
    private ICategoryService categoryService;

    /**
     * 构造spuSaleAttrDto对象
     */
    @PostMapping("/buildAttr")
    public Result<SpuSaleAttrDto> buildAttr(@Validated @RequestBody BuildAttrRequest request){
        SpuSaleAttrDto attr = new SpuSaleAttrDto();
        attr.setName(request.getName());
        return Result.success(attr);
    }

    /**
     * 构造AttrOptionDto对象
     */
    @PostMapping("/buildAttrOption")
    public Result<AttrOptionDto> buildAttrOption(@Validated @RequestBody BuildAttrOptionRequest request){
        AttrOptionDto attr = new AttrOptionDto();
        attr.setAttrName(request.getAttrName());
        attr.setAttrValue(request.getValue());
        attr.setAttrOptionSn(IdUtil.getSnowflakeNextId());
        return Result.success(attr);
    }

    /**
     * 列表
     */
    @PreAuthorize("hasAuthority('product:baseAttr:list')")
    @GetMapping("/list")
    public Result<List<GroupDto>> list(GroupQueryParams request){
        List<GroupDto> list = groupService.list(request);
        return null != list ? Result.success(list) : Result.error();
    }

    /**
     * 根据分类ID查询分组列表（普通属性）
     */
    @GetMapping("/listWithCascade/{categoryId}")
    public Result<List<GroupDto>> listWithCascade(@PathVariable("categoryId") Long categoryId){
        List<Long> categoryIds = categoryService.hierarchyIdList(categoryId);
        List<GroupDto> list = groupService.listWithCascade(new GroupQueryParams().setCategoryIds(categoryIds));
        return null != list ? Result.success(list) : Result.error();
    }

    /**
     * 详情
     */
    @GetMapping("/{id}")
    public Result<GroupDto> info(@PathVariable("id") Long id){
        GroupDto groupDto = groupService.info(id);
        return null != groupDto ? Result.success(groupDto) : Result.error();
    }

    /**
     * 新增
     */
    @OperateRecord(type = OperateTypeEnum.ADD)
    @RepeatSubmit
    @PreAuthorize("hasAuthority('product:baseAttr:save')")
    @PostMapping("/save")
    public Result save(@Validated(value = AddGroup.class) @RequestBody GroupUpdateRequest request){
        groupService.saveEntity(request);
        return Result.success();
    }

    /**
     * 编辑
     */
    @OperateRecord(type = OperateTypeEnum.UPDATE)
    @PreAuthorize("hasAuthority('product:baseAttr:update')")
    @PostMapping("/update")
    public Result update(@Validated(value = UpdateGroup.class) @RequestBody GroupUpdateRequest request){
        groupService.updateEntity(request);
        return Result.success();
    }

    /**
     * 删除
     */
    @OperateRecord(type = OperateTypeEnum.DELETE)
    @PreAuthorize("hasAuthority('product:baseAttr:delete')")
    @PostMapping("/delete/{id}")
    public Result delete(@PathVariable("id") Long id){
        groupService.deleteEntity(id);
        return Result.success();
    }

    /**
     * 交换排序值
     */
    @OperateRecord(type = OperateTypeEnum.UPDATE)
    @PostMapping("/swapSort/{prevGroupId}/{nextGroupId}")
    public Result swapSort(@PathVariable("prevGroupId") Long prevGroupId,
                           @PathVariable("nextGroupId") Long nextGroupId){
        groupService.swapSort(prevGroupId, nextGroupId);
        return Result.success();
    }
}
